package com.education.wisdom.controller.alipay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.education.common.config.BusinessException;
import com.education.common.config.WebSocketServer;
import com.education.common.utils.UUIDUtils;
import com.education.config.AlipayProperties;
import com.education.wisdom.controller.alipay.vo.AliVO;
import com.education.wisdom.feign.UserFeign;
import com.education.wisdom.pojo.CurrencyRecord;
import com.education.wisdom.pojo.Message;
import com.education.wisdom.pojo.SysUser;
import com.education.wisdom.pojo.Textalipay;
import com.education.wisdom.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * 支付宝-电脑网站支付.
 * <p>
 * 电脑网站支付 https://docs.open.alipay.com/270/105898/
 *
 * @author Mengday Zhang
 * @version 1.0
 * @since 2018/6/14
 */
@Controller
@RequestMapping("/alipay/page")
public class AlipayPagePayController {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private AlipayProperties alipayProperties;
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private AlipayController alipayController;
    @Autowired
    private ISysAppLoginService sysAppLoginService;
    @Autowired
    private IUserAccountService accountService;
    @Autowired
    private IPaymentRecordService paymentRecordService;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private ICurrencyRecordService currencyRecordService;
    @Autowired
    private MessageService messageService;
    //由于ConfigurableBeanFactory.SCOPE_PROTOTYPE配置 无法自动注入 需要构造方法注入
    private RabbitTemplate rabbitTemplate;


    @Autowired
    public AlipayPagePayController(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }


    @Value("${pay.url.success}")
    private String successUrl;

    @Value("${pay.url.failire}")
    private String failureUrl;

    @GetMapping("/gotoPayPage")
    public void gotoPayPage(HttpServletResponse response, AliVO aliVO) throws AlipayApiException, IOException {
        logger.info("入参 : 金额  {} 用户id {}", aliVO.getAmount(), aliVO.getUserId());
        //SysAppLogin login=sysAppLoginService.selectSysAppLoginById(userId);
        Map<String, Object> login = userFeign.selectByUserId(Integer.parseInt(aliVO.getUserId()));
        if (login != null) {
            logger.info("用户信息 : {}", login);
            String userName = (String) login.get("name");

            // 订单模型
            String productCode = "FAST_INSTANT_TRADE_PAY";
            AlipayTradePagePayModel model = new AlipayTradePagePayModel();
            String currencyId = UUIDUtils.getByUUId();
            model.setOutTradeNo(currencyId);
            model.setSubject("支付宝支付");
            model.setTotalAmount(aliVO.getAmount());
            model.setBody("支付宝支付，共" + aliVO.getAmount() + "元");
            model.setProductCode(productCode);
            model.setTimeoutExpress("30m");//设置过期时间为30分钟

            //添加支付记录
            CurrencyRecord record = new CurrencyRecord();
            record.setCurrencyId(currencyId);//订单号
            record.setCreateTime(new Date());//创建时间
            record.setStatus("0");//支付状态 1成功  0 支付失败 2 支付中
            record.setUserId(aliVO.getUserId());//创建id
            record.setTrxType("5");//交易业务类型
            record.setPayerName(login.get("name").toString());//创建人名称

            BigDecimal decimal = new BigDecimal(aliVO.getAmount());
            BigDecimal de = new BigDecimal("10");
            String substring = decimal.multiply(de).toString();
            record.setCurrency(new BigDecimal(substring));//支付金额
            record.setRemark("用户支付宝充值");//充值类型
            currencyRecordService.insertCurrencyRecord(record);
            //发消息到mq订单失效修改数据库为支付失败
            //rabbitTemplate.convertAndSend("wisdom_exchange_message", "wisdom_routingkey_delay", currencyId);目前服务器未安装mq会报错无法访问 先注释

            AlipayTradePagePayRequest pagePayRequest = new AlipayTradePagePayRequest();
            pagePayRequest.setReturnUrl(alipayProperties.getReturnUrl());
            pagePayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());
            pagePayRequest.setBizModel(model);


            // 调用SDK生成表单, 并直接将完整的表单html输出到页面
            String form = alipayClient.pageExecute(pagePayRequest).getBody();
            response.setContentType("text/html;charset=" + alipayProperties.getCharset());
            logger.info("出参 : {}", form);
            response.getWriter().write(form);
            response.getWriter().flush();
            response.getWriter().close();
        }
    }


    @GetMapping("/returnUrl")
    public String returnUrl(HttpServletRequest request, HttpServletResponse response, Textalipay textalipay) throws UnsupportedEncodingException, AlipayApiException {
        response.setContentType("text/html;charset=" + alipayProperties.getCharset());

        //商户订单号
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //根据交易订单号查询交易信息
        CurrencyRecord currencyRecord = currencyRecordService.selectByCurrencyId(out_trade_no);

        boolean verifyResult = alipayController.rsaCheckV1(request);
        if (verifyResult) {
            //验证成功

            //修改交易状态为支付成功
            CurrencyRecord record = new CurrencyRecord();
            //订单号
            record.setCurrencyId(out_trade_no);
            //支付状态 1成功  0 支付失败 2 支付中
            record.setStatus("1");
            //修改时间
            record.setEditTime(new Date());
            //交易业务类型
            record.setTrxType("5");
            currencyRecordService.updateCurrencyRecord(record);

            //修改用户达人币
            Map<String, Object> login = userFeign.selectByUserId(Integer.parseInt(currencyRecord.getUserId()));
            logger.error("已有达人币价格 : {}", login.get("price"));
            //Map<String, Object> map = new HashMap<>();
            SysUser user = new SysUser();
            //map.put("id", currencyRecord.getUserId());
            user.setId(Integer.valueOf(currencyRecord.getUserId()));
            BigDecimal price = new BigDecimal(login.get("price").toString());
            //int i = Integer.parseInt(currencyRecord.getCurrency().toString());
            BigDecimal i = (currencyRecord.getCurrency());
            //map.put("price", i.add(price));
            user.setPrice(i.add(price));
            logger.error("充值后的价格 : {}", i);
            userFeign.updatePriceByUserId(user.getId(),user.getPrice());
            logger.info("*************user模块调用完成*************");

            //添加充值信息
            Message message = new Message();
            message.setTitle("支付宝充值成功");
            message.setType("2");
            message.setCreatetime(new Date());
            message.setUserId(Integer.parseInt(currencyRecord.getUserId()));
            message.setIsRead("1");
            messageService.insertMessage(message);
            //查询消息推送
            Integer count = messageService.selectCount(currencyRecord.getUserId());
            try {
                WebSocketServer.sendInfo(count.toString(), currencyRecord.getUserId());
            } catch (IOException e) {
                e.printStackTrace();
            }

            return successUrl;

        } else {
            //修改交易状态为支付失败
            CurrencyRecord record = new CurrencyRecord();
            record.setCurrencyId(trade_no);//订单号
            record.setStatus("0");//支付状态 1成功  0 支付失败 2 支付中
            record.setEditTime(new Date());//修改时间
            record.setTrxType("5");//交易业务类型
            currencyRecordService.updateCurrencyRecord(record);

            //添加充值信息
            Message message = new Message();
            message.setTitle("支付失败 请重新操作");
            message.setType("2");
            message.setCreatetime(new Date());
            message.setUserId(Integer.parseInt(currencyRecord.getUserId()));
            message.setIsRead("1");
            messageService.insertMessage(message);
            //查询消息推送
            Integer count = messageService.selectCount(currencyRecord.getUserId());
            try {
                WebSocketServer.sendInfo(count.toString(), currencyRecord.getUserId());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return failureUrl;

        }
    }


    /**
     * 退款 :
     * 注意 : 如果一个订单已经退款成功后
     * 同一个订单再次请求该接口依旧会返回退款成功信息
     * 该信息是第一次退款成功的信息(详见body信息里的gmt_refund_pay的值 其时间是第一次退款时间)
     *
     * @param
     */
    @GetMapping("/tradeRefund")
    public String tradeRefund(String outTradeNo, String tradeNo, String amount) {
        logger.info("===========支付宝退款============");
        //退款参数
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        //支付时传入的订单号
        model.setOutTradeNo(outTradeNo);
        //支付返回的支付宝交易号
        model.setTradeNo(tradeNo);
        //退款金额
        model.setRefundAmount(amount);
        //商品描述
        model.setRefundReason("支付宝退款");
        //构建请求
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizModel(model);
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new BusinessException("支付宝退款失败");
        }
        if (response.isSuccess()) {
            logger.info("成功信息 : {}", response.getBody());
            return "退款成功";
        } else {
            logger.error("失败信息 : {}", response.getBody());
            throw new BusinessException(response.getSubMsg());
        }
    }

}
